import mongoengine as db
import arrow

from app.db import BaseDocument, BaseEmbeddedDocument
from app.db.models.balances import Feature, Balance
from app.db.models.meta_limit import (
    TypeLimit,
    TypeFreq,
    TypeFreqTotal5,
    TypeLimitTotal20,
    TypeLimitTotal5,
    TypePeriodTotal5,
    TypeFreqTotal3,
    TypeFreqTotal10,
    TypeFreqTotal100000,
    TypeFreqTotal1000,
    TypeFreqTotal100,
    TypePeriod,
    TypeDuration,
    TypeLimitTotal50,
    ExpTypeLimit
)
from app.libs.enums import ChargeType


class LimitDefault(BaseEmbeddedDocument):
    domain = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)
    domainEnable = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)

    # http
    httpMaxTask = db.EmbeddedDocumentField(TypeLimit, default=TypeLimitTotal20)
    httpMaxTaskEnable = db.EmbeddedDocumentField(TypeLimit, default=TypeLimitTotal20)
    httpMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    httpMaxNode = db.EmbeddedDocumentField(TypeFreqTotal5, default=TypeFreqTotal5)

    # ping
    pingMaxTask = db.EmbeddedDocumentField(TypeLimit, default=TypeLimitTotal5)
    pingMaxTaskEnable = db.EmbeddedDocumentField(TypeLimit, default=TypeLimitTotal5)
    pingMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    pingMaxNode = db.EmbeddedDocumentField(TypeFreqTotal5, default=TypeFreqTotal5)

    # vul
    vulManualTask = db.EmbeddedDocumentField(TypePeriodTotal5, default=TypePeriodTotal5)
    vulMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    vulMaxDepth = db.EmbeddedDocumentField(TypeFreqTotal10, default=TypeFreqTotal10)
    vulMaxPage = db.EmbeddedDocumentField(TypeFreqTotal100000, default=TypeFreqTotal100000)

    # sitePortrait
    sitePortrait = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)

    # ssl
    sslMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    sslManualTask = db.EmbeddedDocumentField(TypePeriodTotal5, default=TypePeriodTotal5)

    # securityEvent
    securityEventMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    securityEventManualTask = db.EmbeddedDocumentField(TypePeriodTotal5, default=TypePeriodTotal5)
    securityEventMaxDepth = db.EmbeddedDocumentField(TypeFreqTotal10, default=TypeFreqTotal10)
    securityEventMaxPage = db.EmbeddedDocumentField(TypeFreqTotal100000, default=TypeFreqTotal100000)

    # asset
    assetMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    assetManualTask = db.EmbeddedDocumentField(TypePeriodTotal5, default=TypePeriodTotal5)

    # content
    contentMaxDepth = db.EmbeddedDocumentField(TypeFreqTotal10, default=TypeFreqTotal10)
    contentMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    contentManualTask = db.EmbeddedDocumentField(TypePeriodTotal5, default=TypePeriodTotal5)
    contentMaxPage = db.EmbeddedDocumentField(TypeFreqTotal100000, default=TypeFreqTotal100000)

    # ipv6
    ipv6ManualTask = db.EmbeddedDocumentField(TypePeriodTotal5, default=TypePeriodTotal5)

    # other
    maxPage = db.EmbeddedDocumentField(TypePeriod, default=TypePeriod)
    aviliableMaxHistory = db.EmbeddedDocumentField(TypeDuration, default=TypeDuration)
    whitelist = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)
    smsAlert = db.EmbeddedDocumentField(TypePeriod, default=TypePeriod)
    emailAlert = db.EmbeddedDocumentField(TypePeriod, default=TypePeriod)
    alertGroup = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)
    alertReceiver = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)
    maxHistory = db.EmbeddedDocumentField(TypeDuration, default=TypeDuration)
    urlBLSMaxNum = db.EmbeddedDocumentField(TypeLimitTotal50, default=TypeLimitTotal50)
    api = db.EmbeddedDocumentField(ExpTypeLimit, default=ExpTypeLimit)

    # 主机监测
    host = db.EmbeddedDocumentField(TypeLimit, default=TypeLimit)
    hostVulMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)
    hostVulManualTask = db.EmbeddedDocumentField(TypePeriod, default=TypePeriod)

    # 篡改监测
    changeCheckMaxFreq = db.EmbeddedDocumentField(TypeFreq, default=TypeFreq)   # 最大监测频率
    changeCheckMaxDepth = db.EmbeddedDocumentField(TypeFreqTotal10, default=TypeFreqTotal10)  # 最大监测深度
    changeCheckMaxPage = db.EmbeddedDocumentField(TypeFreqTotal1000, default=TypeFreqTotal1000)   # 最大监测URL数
    changeCheckMaxBaseChange = db.EmbeddedDocumentField(TypeFreqTotal5, default=TypeFreqTotal5)  # 样本更新最大频率， 根据任务执行次数
    changeCheckMaxKeyword = db.EmbeddedDocumentField(TypeFreqTotal100, default=TypeFreqTotal100)  # 自定义敏感词最大数量
    changeCheckMaxResource = db.EmbeddedDocumentField(TypeFreqTotal100, default=TypeFreqTotal100)  # 重点关注资源最大数量


class Packages(BaseDocument):
    meta = {
        'strict': False,
        'collection': 'packages',
    }

    name = db.StringField(default='', required=True)
    key = db.StringField(default='', required=True)
    chargeType = db.StringField(default=ChargeType.plan.value, choices=[item.value for item in ChargeType])
    createTime = db.DateTimeField()
    limit = db.EmbeddedDocumentField(default=Balance, document_type=Balance)
    marks = db.StringField(default='')
    feature = db.EmbeddedDocumentField(default=Feature, document_type=Feature)
    operator = db.StringField(default='')
    packageMarks = db.StringField(default='', required=True)

    def save(self, *args, **kwargs):
        now_datetime = arrow.utcnow().datetime
        if not self.createTime:
            self.createTime = now_datetime
        return super(Packages, self).save(*args, **kwargs)
